#ifndef MACRO_HPP
#define MACRO_HPP

#include "shared_values.h"
#include <LittleFS.h>

const char* macro_path = "/macro.txt"; // 修改为以 / 开头的绝对路径

// stepper->motorSpeed(0); // 停止电机
// stepper->motorSpeed(1000); // 正转速度1000
// stepper->motorSpeed(-1000); // 反转速度1000

int macro_position = 0; // 全局变量，记录宏文件执行到的位置
bool macro_running = false; // 全局变量，标志宏是否正在执行

// 宏命令类型
enum MacroType {
    FREQ_CHANGE,  // f命令
    SLEEP,        // s命令
};

// 宏命令结构
struct MacroCommand {
    MacroType type;
    int value;
    MacroCommand* next;
    
    MacroCommand(MacroType t, int v) : type(t), value(v), next(nullptr) {}
};

// 宏命令链表管理
class MacroList {
private:
    MacroCommand* head;
    MacroCommand* current;
    int size;
    static const int MAX_SIZE = 100;

public:
    MacroList() : head(nullptr), current(nullptr), size(0) {}
    
    ~MacroList() {
        clear();
    }

    void clear() {
        while (head) {
            MacroCommand* temp = head;
            head = head->next;
            delete temp;
        }
        current = nullptr;
        size = 0;
    }

    bool add(MacroType type, int value) {
        if (size >= MAX_SIZE) return false;
        
        MacroCommand* cmd = new MacroCommand(type, value);
        if (!head) {
            head = cmd;
        } else {
            MacroCommand* temp = head;
            while (temp->next) temp = temp->next;
            temp->next = cmd;
        }
        size++;
        return true;
    }

    void resetCurrent() {
        current = head;
    }

    MacroCommand* getNext() {
        if (!current) return nullptr;
        MacroCommand* temp = current;
        current = current->next;
        return temp;
    }

    void showCommands() {
        MacroCommand* temp = head;
        int index = 0;
        Serial.println("[UMEKO][MACRO] 已加载的宏命令列表:");
        while (temp) {
            if (temp->type == FREQ_CHANGE) {
                Serial.printf("  %3d: f%d\n", index, temp->value);
            } else if (temp->type == SLEEP) {
                Serial.printf("  %3d: s%d\n", index, temp->value);
            }
            temp = temp->next;
            index++;
        }
        Serial.printf("[UMEKO][MACRO] 共%d条命令\n", size);
    }
};

MacroList macroList;

void load_macro() {
    if (!LittleFS.begin()) {
        Serial.println("[UMEKO][FS] LittleFS初始化失败");
        return;
    }

    if (!LittleFS.exists(macro_path)) {
        Serial.printf("[UMEKO][FS] 宏文件 \"%s\" 不存在\n", macro_path);
        return;
    }

    fs::File macroFile = LittleFS.open(macro_path, "r");
    if (!macroFile) {
        Serial.printf("[UMEKO][FS] 无法打开宏文件 \"%s\"\n", macro_path);
        return;
    }

    macroList.clear();
    int totalLines = 0;
    int loadedLines = 0;
    bool capacityWarning = false;
    while (macroFile.available()) {
        String line = macroFile.readStringUntil('\n');
        line.trim();
        totalLines++;

        if (line.startsWith("f")) {
            int speed = line.substring(1).toInt();
            if (!macroList.add(FREQ_CHANGE, speed)) {
                if (!capacityWarning) {
                    Serial.printf("[UMEKO][MACRO] 警告：宏命令数量超过100条，后续命令将被忽略（总行数：%d）\n", totalLines);
                    capacityWarning = true;
                }
            } else {
                loadedLines++;
            }
        } else if (line.startsWith("s")) {
            int delay = line.substring(1).toInt();
            if (!macroList.add(SLEEP, delay)) {
                if (!capacityWarning) {
                    Serial.printf("[UMEKO][MACRO] 警告：宏命令数量超过100条，后续命令将被忽略（总行数：%d）\n", totalLines);
                    capacityWarning = true;
                }
            } else {
                loadedLines++;
            }
        }
    }
    macroFile.close();
    Serial.printf("[UMEKO][MACRO] 宏加载完成：共%d行，成功加载%d行\n", totalLines, loadedLines);
}

void start_macro() {
    macroList.resetCurrent();
    macro_running = true;
    macro_position = 0;
    Serial.println("[UMEKO][MACRO] 宏文件已加载，开始执行");
}

void stop_macro() {
    macro_running = false; // 停止宏执行模式
    macro_position = 0;    // 重置行数
    Serial.println("[UMEKO][MACRO] 宏执行已停止");
}

void macro_looper() {
    static unsigned long lastActionTime = 0;
    static bool isDelayActive = false;
    static int delayDuration = 0;

    if (!macro_running) return;

    if (isDelayActive) {
        if (millis() - lastActionTime >= delayDuration) {
            isDelayActive = false;
            Serial.printf("[%6lu][UMEKO][MACRO] 延迟完成\n", millis());
        } else {
            return;
        }
    }

    MacroCommand* cmd = macroList.getNext();
    if (cmd) {
        macro_position++;
        if (cmd->type == FREQ_CHANGE) {
            Serial.printf("[%6lu][UMEKO][MACRO] 设置电机速度: %d\n", millis(), cmd->value);
            stepper->motorSpeed(cmd->value);
        } else if (cmd->type == SLEEP) {
            Serial.printf("[%6lu][UMEKO][MACRO] 开始延迟: %d 毫秒\n", millis(), cmd->value);
            isDelayActive = true;
            delayDuration = cmd->value;
            lastActionTime = millis();
        }
    } else {
        macro_running = false;
        Serial.printf("[%6lu][UMEKO][MACRO] 宏执行完成\n", millis());
    }
}

void show_macro() {
    macroList.showCommands();
}

#endif // MACRO_HPP